package everydayone.twitter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Date 2020/04/13
 * @author 王光浩
 * @Thinking 使用 Map<Integer,List> twitter ——存储每一个用户和其发送的推特
 * 			  使用 Map<Integer,Set<Integer>> follow ——存储每一个用户关注的对象（包括他自己）
 * 			  另外这里还需要一个全局变量，这个全局变量用于存储每一个推特的时间戳。
 * 		发送推特：首先判断在 twitter 中是否存储在用户，如果不存在则创建该用户，并发送推特（同理需要判断是否存在 follow）
 * 		接受消息：首先获取 follow 中的用户的所有关注对象的 List，然后从其中获取时间戳最大的前10个（注意要判断用户是否存在）
 * 		关注其他用户：在 首先判断用户是否存在，且用户不能关注自己。然后自己关注即可
 * 		取消关注：首先判断用户是否存在，然后用户不能取消关注自己，然后直接关注即可。
 */
public class MyMethodTwo {
	private class Tweet {
		int tweetId;
		int time;
		Tweet next;
		public Tweet(int time,int tweetId) {
			this.time = time;
			this.tweetId = tweetId;
		}
	}
	private int count = 0;
	private Map<Integer,Tweet> twitter;
	private Map<Integer,Set<Integer>> follow;
	
	public MyMethodTwo() {
		twitter = new HashMap<Integer,Tweet>();
		follow = new HashMap<Integer,Set<Integer>>();
	}
	
	/**
	 * 创建一个 Tweet ，然后将该推塔加入到 twitter 中
	 * @param userId   用户
	 * @param tweetId  内容
	 */
	public void postTweet(int userId, int tweetId) {
		Tweet newTw = new Tweet(count++,tweetId);
		if(!twitter.containsKey(userId)) {
			follow.put(userId, new HashSet<Integer>());
			follow.get(userId).add(userId);
		}
		if(twitter.containsKey(userId)) {
			Tweet oldTw=twitter.get(userId);
			newTw.next=oldTw;
		}
		twitter.put(userId, newTw);
	}
	
	/**
	 * 获取用户和其关注者的前10条记录
	 * @param userId
	 * @return
	 */
	public List<Integer> getNewsFeed(int userId) {
		List<Integer> ret = new LinkedList<Integer>();
		if(!follow.containsKey(userId)) return ret;
		Set<Integer> user = follow.get(userId);
		//每一个对象指向 对应的 推文
		ArrayList<Tweet> followee=new ArrayList<Tweet>(user.size());
		for (int i : user) {
			followee.add(twitter.get(i)) ;
		}
		//获取 userId 关注对象的前 10 个推特
		Tweet max = null ;
		Tweet last = null;
		for ( int total = 0; total < 10 ; total++) {
			int maxTime = -1;  //当前最大的时间
			for(int i= 0 ;i < followee.size();i++) {
				if(followee.get(i) != null) {
					if(followee.get(i).equals(last) ) followee.set(i, followee.get(i).next);
					if(followee.get(i) == null ) continue;
					if(followee.get(i).time > maxTime) {
						max = followee.get(i);
						maxTime = followee.get(i).time;
					}
				}
			}
			if( maxTime != -1 ) {
				last = max;
				ret.add( max.tweetId); 
			}
		}
		return ret;
    }
	
	public void follow(int followerId, int followeeId) {
		if(!twitter.containsKey(followerId)) {
			twitter.put(followerId, null);
			follow.put(followerId, new HashSet<Integer>());
			follow.get(followerId).add(followerId);
		}
		if(!twitter.containsKey(followeeId)) {
			twitter.put(followeeId, null);
			follow.put(followeeId, new HashSet<Integer>());
			follow.get(followeeId).add(followeeId);
		}
		if( followerId == followeeId )return ;
		follow.get(followerId).add(followeeId);
		
    }
	
	 public void unfollow(int followerId, int followeeId) {
		 if(!twitter.containsKey(followerId)) {
				twitter.put(followerId, null);
				follow.put(followerId, new HashSet<Integer>());
				follow.get(followerId).add(followerId);
		 }
		 if(followerId != followeeId 
				 && twitter.containsKey(followeeId) 
				 && follow.get(followerId).contains(followeeId) )
			 follow.get(followerId).remove(followeeId);
		 
			 
	 }
}
